/**
 * UFCG - CEEI - DSC- SI1
 * Projeto da Disciplina Sistema de Informacao 1 - 2011.1
 * 
 * Professor: Hyggo Almeida
 * 
 * Alunos: Felipe de Sousa - felipeso@lcc.ufcg.edu.br
 * 		   Matheus Sampaio - matheusss@lcc.ufcg.edu.br
 *         Henrique Florencio - henriquecf@lcc.ufcg.edu.br
 *         Claudio Cardoso - claudiocaj@lcc.ufcg.edu.br
 * 		   Julio Henrrique - juliohr@lcc.ufcg.edu.br
 * 
 */

package controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import model.Evento;
import model.SalaIF;
import persistencia.Serializador;

public class GerenciadorDeDados {

	private static final String FILE_SEPARATOR = System
			.getProperty("file.separator");

	private final String FILE_SALAS = "ArquivoDeSalas";
	private final String FILE_EVENTOS = "ArquivoDeEventos";
	private final String FILE_EVENTOSALOCADOS = "ArquivoDeEventosAlocados";

	private static GerenciadorDeDados gerenciadorDeDados;

	private ArrayList<SalaIF> ListSala = new ArrayList<SalaIF>();
	private ArrayList<Evento> ListEvento = new ArrayList<Evento>();

	public static synchronized GerenciadorDeDados getInstance() {

		if (gerenciadorDeDados == null)
			gerenciadorDeDados = new GerenciadorDeDados();

		return gerenciadorDeDados;
	}

	/**
	 * Exclui o arquivo desejado.
	 * 
	 * @param caminhoArquivo
	 *            - o nome do arquivo a ser excluido.
	 */
	private static void excluir(String caminhoArquivo) {
		new File(caminhoArquivo).delete();

	}

	/**
	 * Metodo responsavel por retornar um Iterator de Eventos salvos no arquivo.
	 * 
	 * @return um iterator de Eventos.
	 */
	@SuppressWarnings("unchecked")
	protected Iterator<Evento> loadEventos() {

		try {
			ListEvento = (ArrayList<Evento>) Serializador
					.recuperar(FILE_EVENTOS);
		} catch (Exception e) {
			ListEvento = new ArrayList<Evento>();
		}

		return iteratorEvento();
	}

	/**
	 * Metodo responsavel por retornar o Mapa de eventos alocados salvos no arquivo.
	 * 
	 * @return um {@link Map} de eventos e salas.
	 */
	@SuppressWarnings("unchecked")
	protected Map<Evento, SalaIF> loadEventosAlocados() {

		Map<Evento, SalaIF> map = null;

		try {
			map = (Map<Evento, SalaIF>) Serializador.recuperar(FILE_EVENTOS);
		} catch (Exception e) {
			map = new HashMap<Evento, SalaIF>();
		}

		return map;
	}

	/**
	 * Metodo responsavel por retornar um iterator de Salas que esta no arquivo.
	 * 
	 * @return um iterator de Salas
	 * 
	 */
	@SuppressWarnings("unchecked")
	protected Iterator<SalaIF> loadSalas() {

		try {
			ListSala = (ArrayList<SalaIF>) Serializador.recuperar(FILE_SALAS);
		} catch (Exception e) {
			ListSala = new ArrayList<SalaIF>();
		}

		return iteratorSala();
	}

	/**
	 * Metodo responsavel por salvar um array de Eventos no arquivo.
	 * 
	 */
	protected void saveEventos() {

		Serializador.salvar(FILE_EVENTOS, ListEvento);
	}

	/**
	 * Metodo resposavel por salvar um mapa de eventos e salas em um arquivo.
	 * 
	 * @param eventoAlocado
	 *            - um {@link Map} a ser salvo.
	 */
	protected void saveEventosAlocados(Map<Evento, SalaIF> eventoAlocado) {

		Serializador.salvar(FILE_EVENTOSALOCADOS, eventoAlocado);
	}

	/**
	 * Metodo que salva um array de Salas no arquivo arquivo.
	 * 
	 */
	protected void saveSalas() {

		Serializador.salvar(FILE_SALAS, ListSala);
	}

	/**
	 * Metodo usando para adicionar uma sala ao array
	 * @param sala um objeto do tipo sala
	 */
	protected void salasAdd(SalaIF sala) {
		ListSala.add(sala);
	}

	/**
	 * Metodo responsalvel por salvar um evento no array
	 * @param even um objeto do tipo evento
	 */
	protected void eventosAdd(Evento even) {
		ListEvento.add(even);
	}

	/**
	 * Exclui todos os arquivos existentes no banco de dados.
	 */
	protected void zeraSistema() {

		ListSala = new ArrayList<SalaIF>();
		ListEvento = new ArrayList<Evento>();

		try {
			String diretorio = new File(".").getCanonicalPath();
			File dir = new File(diretorio);
			if (dir.isDirectory()) {
				String[] listArq = dir.list();
				for (int i = 0; i < listArq.length; i++)
					if (listArq[i].endsWith(".dat"))
						excluir(diretorio + FILE_SEPARATOR + listArq[i]);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Metodo que retorna um iterator
	 * 
	 * @return um iterator do tipo SalaIF
	 */
	protected Iterator<SalaIF> iteratorSala() {
		return new Iterator<SalaIF>() {
			int cursor = 0;

			public boolean hasNext() {
				return cursor < ListSala.size();
			}

			public SalaIF next() {
				SalaIF current = ListSala.get(cursor);
				cursor += 1;
				return current;
			}

			public void remove() {
				ListSala.remove(cursor - 1);

			}

		};
	}

	/**
	 * Metodo que retorna um iterator
	 * 
	 * @return um iterator do tipo Evento
	 */
	protected Iterator<Evento> iteratorEvento() {
		return new Iterator<Evento>() {
			int cursor = 0;

			public boolean hasNext() {
				return cursor < ListEvento.size();
			}

			public Evento next() {
				Evento current = ListEvento.get(cursor);
				cursor += 1;
				return current;
			}

			public void remove() {
				ListEvento.remove(cursor - 1);

			}

		};
	}

}
